﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ClassLibrary;

namespace RDPProxyClient
{
    public class CoreCode : IDisposable
    {
        public ClientSetting ClientSetting { get; set; }

        private bool _stop = false;

        #region 核心代码 

        private NetworkStream _kongzhins = null;

        public CoreCode(ClientSetting clientSetting)
        {
            ClientSetting = clientSetting;
        }

        public void Stop()
        {
            this._stop = true;
            this._kongzhins?.Close();
            this._kongzhins?.Dispose();
            _tc?.Close();
        }

        protected void Delay(int millisecond)
        {
            Thread t = new Thread(o => Thread.Sleep(millisecond));
            t.Start();
            while (t.IsAlive)
            {
                Thread.Sleep(100);
            }
        }

        private TcpClient _tc = null;
        public void DoConnect()
        {

        

            try
            {
                //tc = new TcpClient("211.149.226.80", 8080)
                _tc = new TcpClient(ClientSetting.ServerAddress, ClientSetting.ServerPort)
                {
                    SendTimeout = 30 * 1000,
                    ReceiveTimeout = 30 * 1000
                };
                System.Console.WriteLine("连接成功");
                _kongzhins = _tc.GetStream();
                byte[] bt = Encoding.Default.GetBytes("ok");//这里发送一个连接提示  
                _kongzhins.Write(bt, 0, bt.Length);
                Jieshou();
                //WaitHandle.WaitAll(new WaitHandle[] { new ManualResetEvent(false) });//这里为什么要这样呢?我发现sqlserver执行是localsystem账号如果console.read()程序马上退出  
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.Message);

                Delay(1000 * 5);
                if (_stop)
                {
                    this._kongzhins?.Close();
                    this._kongzhins?.Dispose();
                    _tc?.Close();
                    return;
                }
                if (_tc != null && _tc.Connected)
                    _tc.Close();
                DoConnect();
                //System.Console.ReadLine();
            }
        }

        protected void Jieshou()
        {
            while (true)
            {
                byte[] bt = new byte[4];
                _kongzhins.Read(bt, 0, bt.Length);
                //TcpClient tc1 = new TcpClient("211.149.226.80", 8080);
                TcpClient tc1 = new TcpClient(ClientSetting.ServerAddress, ClientSetting.ServerPort);
                //TcpClient tc2 = new TcpClient("localhost", 3389);
                TcpClient tc2 = new TcpClient("localhost", ClientSetting.ClientPort);
                tc1.SendTimeout = 30 * 1000;
                tc1.ReceiveTimeout = 30 * 1000;
                tc2.SendTimeout = 30 * 1000;
                tc2.ReceiveTimeout = 30 * 1000;
                tc1.GetStream().Write(bt, 0, bt.Length);
                object obj1 = (object)(new TcpClient[] { tc1, tc2 });
                object obj2 = (object)(new TcpClient[] { tc2, tc1 });
                ThreadPool.QueueUserWorkItem(new WaitCallback(Transfer), obj1);
                ThreadPool.QueueUserWorkItem(new WaitCallback(Transfer), obj2);
            }
        }

        protected void Transfer(object obj)
        {
            TcpClient tc1 = ((TcpClient[])obj)[0];
            TcpClient tc2 = ((TcpClient[])obj)[1];
            NetworkStream ns1 = tc1.GetStream();
            NetworkStream ns2 = tc2.GetStream();
            while (true)
            {
                try
                {
                    byte[] bt = new byte[10240];
                    int count = ns1.Read(bt, 0, bt.Length);
                    ns2.Write(bt, 0, count);
                }
                catch
                {
                    ns1.Close();
                    ns1.Dispose();
                    ns2.Close();
                    ns2.Dispose();
                    tc1.Close();
                    tc2.Close();
                    break;
                }
            }
        }

        #endregion

        ~CoreCode()
        {
            Dispose();
        }

        public void Dispose()
        {
            Dispose(true);//这样会释放所有的资源
            GC.SuppressFinalize(this);//不需要再调用本对象的Finalize方法
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                //清理托管资源
            }
            //清理非托管资源

        }
    }
}
